<template>
  <Card>
    <Button type="primary" @click="showSaveModal">
      <!-- 命名/具名插槽：用来显示图标 -->
      <template #icon><PlusOutlined /></template>
      <!-- 默认插槽：用来显示文字 -->
      添加品牌
    </Button>

    <Table
      class="mt-15px"
      :columns="columns"
      :data-source="trademarkList"
      bordered
      :pagination="{
        current, // 当前页码
        pageSize, // 每页条数
        total, // 总数
        pageSizeOptions: ['3', '6', '9', '12'], // 指定每页可以显示多少条
        position: ['bottomCenter'], // 分页器显示位置
        showQuickJumper: true, // 是否可以快速跳转至某页
        showSizeChanger: true, // 是否可以改变 pageSize
        showTotal: (total) => `总共 ${total} 条`, // 用于显示数据总量和当前数据顺序
        // 文档有些差异：加上on，改为小驼峰命名
        // https://next.antdv.com/components/pagination-cn#%E4%BA%8B%E4%BB%B6
        onChange: getTrademarkList, // 当前页码发生变化触发的回调
        onShowSizeChange: getTrademarkList, // 每页条数发生变化触发的回调
      }"
      rowKey="id"
      :loading="tableLoading"
    >
      <!-- 
        默认情况下：table每一列渲染的内容看columns - dataIndex 对应值
        下面具名插槽#bodyCell，可以改变要渲染的内容
        "{ text, record, index, column }" 作用域插槽
          text 代表 dataIndex 对应数据的值
          record 代表 整行数据
          index 代表 下标
          column 代表 列的情况

        table结论：
          1. 如果想要直接渲染数据 dataIndex
          2. 如果想要渲染其他内容（不是直接数据）
            按钮 图片等
            用bodyCell方式渲染
      -->
      <template #bodyCell="{ column, text, record, index }">
        <template v-if="column.dataIndex === 'logoUrl'">
          <img :src="text" :alt="record.tmName" class="w-200px h-100px" />
          <!-- <img :src="record.logoUrl" :alt="record.tmName" /> -->
        </template>
        <template v-if="column.dataIndex === 'operator'">
          <!-- 
            windicss的文档：https://windicss.org/utilities/colors.html
          -->
          <Button
            class="
              !text-orange-500
              !border-orange-500
              hover:(!text-orange-300
              !border-orange-300)
              mr-10px
            "
            @click="showUpdateModal(record)"
          >
            <template #icon><EditOutlined /></template>
            更新品牌
          </Button>
          <Popconfirm
            :title="`您确认要删除 ${record.tmName} 品牌数据吗？`"
            @confirm="removeTrademark(record.id)"
          >
            <template #icon><QuestionCircleOutlined style="color: red" /></template>
            <Button danger>
              <template #icon><DeleteOutlined /></template>
              删除品牌
            </Button>
          </Popconfirm>
        </template>
        <template v-if="column.dataIndex === 'id'">
          {{ index + 1 }}
        </template>
      </template>
    </Table>
    <!-- 
      v-model:visible="visible" 决定对话框显示&隐藏
      title 标题
      @ok 事件，点击确定按钮触发的事件
     -->
    <Modal
      v-model:visible="visible"
      :title="`${trademark.id ? '更新' : '添加'}品牌`"
      @ok="addTrademark"
      @cancel="formRef.clearValidate()"
      :confirmLoading="confirmLoading"
    >
      <!-- 
        ref="formRef" 获取Form组件的实例对象，将来可以使用上面的方法 validate resetFields
        :model="xxx" 绑定表单所有数据
        :rules="xxx" 绑定表单的验证规则
        label-col 
        wrapper-col
       -->
      <Form
        class="!mt-20px"
        ref="formRef"
        :model="trademark"
        :rules="rules"
        :label-col="{ span: 4 }"
        :wrapper-col="{ span: 14 }"
      >
        <!-- 
          label 左侧文本
          name 用rules的哪个规则
         -->
        <FormItem label="品牌名称" name="tmName">
          <Input placeholder="请输入品牌名称" v-model:value="trademark.tmName" />
        </FormItem>

        <FormItem label="品牌LOGO" name="logoUrl">
          <!-- 
            Upload 上传图片组件
              list-type="picture-card" 样式效果（卡片形式）
              :show-upload-list="false" 是否上传多张图片 
              action="xxx" 上传图片到某个服务器地址
                action="http://39.98.123.211/admin/product/fileUpload"
                action="/dev-api/admin/product/fileUpload" 会走代理服务器
                :action="`${apiUrl}/admin/product/fileUpload`"
                :before-upload="beforeUpload" 上传之前触发回调
                  检查图片大小和格式是否符合要求
                @change="handleChange" 图片上传中触发的回调
                  上传中
                  上传成功 / 上传失败
           -->
          <Upload
            list-type="picture-card"
            :show-upload-list="false"
            :action="`${apiUrl}/admin/product/fileUpload`"
            :before-upload="beforeUpload"
            @change="handleChange"
          >
            <!-- 
              trademark.logoUrl 上传成功的图片地址

              上传成功：显示图片
              上传中：显示loading
              上传之前：显示 +
             -->
            <!-- 上传成功 -->
            <img v-if="trademark.logoUrl" :src="trademark.logoUrl" alt="avatar" />
            <div v-else>
              <!-- 上传中 -->
              <LoadingOutlined v-if="uploadLoading" />
              <!-- 上传之前 -->
              <!-- 组件内部有内容，用双标签，没有内容用单标签 -->
              <PlusOutlined v-else />
              <div class="ant-upload-text">Upload</div>
            </div>
          </Upload>
        </FormItem>
      </Form>
    </Modal>
  </Card>
</template>

<script lang="ts">
  import { defineComponent } from 'vue';

  // export default {
  //   name: 'Trademark',
  // };

  export default defineComponent({
    name: 'Trademark',
  });
</script>

<script lang="ts" setup>
  import { onMounted, ref, reactive, toRaw } from 'vue';
  // 在setup语法中，引入组件会自动注册组件
  import {
    Card,
    Button,
    Table,
    Modal,
    Form,
    FormItem,
    Input,
    Upload,
    message,
    Popconfirm,
  } from 'ant-design-vue';
  // 图标引入才能使用
  import {
    PlusOutlined,
    EditOutlined,
    DeleteOutlined,
    LoadingOutlined,
    QuestionCircleOutlined,
  } from '@ant-design/icons-vue';
  // 引入请求接口函数
  import {
    getTrademarkListApi,
    saveTrademarkApi,
    updateTrademarkApi,
    removeTrademarkApi,
  } from '/@/api/product/trademark';
  // 引入类型 - 加上type
  import type { TrademarkListModel, TrademarkModel } from '/@/api/product/model/trademarkModel';
  import type { FileInfo, FileItem } from '../file';

  import { useGlobSetting } from '/@/hooks/setting';
  // 功能：删除品牌
  const removeTrademark = async (id: number) => {
    await removeTrademarkApi(id);
    message.success('删除数据成功');
    getTrademarkList(current.value, pageSize.value);
  };

  // 功能：更新品牌
  const showSaveModal = () => {
    trademark.tmName = '';
    trademark.logoUrl = '';
    trademark.id = undefined;

    visible.value = true;
    // formRef.value.clearValidate();
  };

  const showUpdateModal = (record: TrademarkModel) => {
    // console.log(record); // 当前行数据 id tmName logoUrl
    trademark.tmName = record.tmName;
    trademark.logoUrl = record.logoUrl;
    trademark.id = record.id;

    visible.value = true;
    // formRef.value.clearValidate();
  };

  // 功能：添加品牌
  // 对话框显示&隐藏
  const visible = ref(false);
  const confirmLoading = ref(false);
  // Form组件的实例对象
  const formRef = ref();
  // 添加品牌的表单数据
  const trademark = reactive<TrademarkModel>({
    id: undefined,
    tmName: '',
    logoUrl: '',
  });
  // 表单规则
  const rules = {
    // key 规则名称 --> 必须要求和数据名称一致
    // value 规则内容
    tmName: [{ required: true, message: '请输入品牌名称', trigger: 'blur' }],
    logoUrl: [{ required: true, message: '请上传品牌LOGO' }],
  };

  // 添加或更新品牌的函数
  const addTrademark = async () => {
    // 进行表单验证
    await formRef.value.validate();

    confirmLoading.value = true;
    // 发送请求
    // console.log(trademark); // 响应式数据
    // toRaw 将响应式数据转换为原数据
    // console.log(toRaw(trademark)); // 原数据
    if (trademark.id) {
      // 更新
      await updateTrademarkApi(toRaw(trademark));
    } else {
      // 添加
      await saveTrademarkApi(toRaw(trademark));
    }

    confirmLoading.value = false;
    // 隐藏对话框
    visible.value = false;
    message.success(`${trademark.id ? '更新' : '添加'}品牌成功`);
    getTrademarkList(current.value, pageSize.value);
  };

  // 图片上传loading
  const uploadLoading = ref(false);
  // 图片上传地址前缀
  const { apiUrl } = useGlobSetting();
  // 图片上传之前触发的回调
  const beforeUpload = (file: FileItem) => {
    // file.type 文件类型
    const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
    if (!isJpgOrPng) {
      message.error('只能上传jpg和png格式的图片!');
    }
    // file.size 文件大小
    const isLt = file.size / 1024 < 500;
    if (!isLt) {
      message.error('图片大小不能超过500KB!');
    }
    // 返回值true ok
    // 返回值false，就不能够上传
    return isJpgOrPng && isLt;
  };
  // 图片上传中触发的回调
  const handleChange = (info: FileInfo) => {
    // 上传中: 切换loading状态
    if (info.file.status === 'uploading') {
      uploadLoading.value = true;
      return;
    }
    // 上传成功：得到图片地址
    if (info.file.status === 'done') {
      // Get this url from response in real world.
      // console.log('上传成功');
      trademark.logoUrl = info.file.response.data;
      uploadLoading.value = false;
    }
    // 上传失败：提示错误
    if (info.file.status === 'error') {
      uploadLoading.value = false;
      message.error('上传图片失败');
    }
  };

  // 功能：品牌列表分页展示
  // table中列
  const columns = [
    {
      title: '序号', // 列头的标题
      dataIndex: 'id', // 渲染data中哪个数据
      width: 80, // 宽度
      align: 'center', // 居中
    },
    {
      title: '品牌名称',
      dataIndex: 'tmName',
    },
    {
      title: '品牌LOGO',
      dataIndex: 'logoUrl',
    },
    {
      title: '操作',
      dataIndex: 'operator',
      width: 300,
    },
  ];
  // table中数据
  const trademarkList = ref<TrademarkListModel>([
    // {
    //   key: '1',
    //   name: 'John Brown',
    //   money: '￥300,000.00',
    //   address: 'New York No. 1 Lake Park',
    // },
  ]);

  // 当前页码
  const current = ref<number>(1);
  // 每页条数
  const pageSize = ref<number>(3);
  // 总数
  const total = ref<number>(0);

  const tableLoading = ref(false);

  // 封装一个发送请求的函数
  const getTrademarkList = async (page: number, limit: number) => {
    tableLoading.value = true;
    // 发送请求，获取分页列表
    const res = await getTrademarkListApi(page, limit);
    trademarkList.value = res.records;
    total.value = res.total;
    current.value = page;
    pageSize.value = limit;
    tableLoading.value = false;
  };

  onMounted(async () => {
    getTrademarkList(current.value, pageSize.value);
  });
</script>
